package com.example.seckill.Interceptor;

import com.example.seckill.Exception.ErrorEnum;
import com.example.seckill.Exception.GlobalException;
import com.example.seckill.Util.JwtTokenUtil;
import com.example.seckill.annotation.AccessLimit;
import com.example.seckill.mapper.RoleMapper;
import com.example.seckill.mapper.UserMapper;
import com.example.seckill.pojo.User;
import com.example.seckill.pojo.UserRole;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


//自定义权限拦截器AuthenticationInterceptor，
// 需实现HandlerInterceptor。
// 在preHandle中调用tokenUtils.getUserByToken(token)，获取到当前用户，最后塞进request中，
@Component
//@PropertySource("classpath:application.yaml")
public class LoginInterceptor implements HandlerInterceptor {

@Autowired
private JwtTokenUtil jwtTokenUtil ;
@Autowired
UserMapper userMapper;

@Autowired
    RedisTemplate redisTemplate;
@Autowired
    RoleMapper roleMapper;


//    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        System.out.println("=====preHandle=====");
        //跨域会先发送option请求，直接通过拦截器
        if(request.getMethod().equals("OPTIONS")){
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }

        // 检查是否存在Token
        String authorizationHeader = request.getHeader("Authorization");
        System.out.println("header= "+authorizationHeader);
        if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
            throw new GlobalException(ErrorEnum.NO_TOKEN_FOUND);

        }

        String token = authorizationHeader.substring(7); // 去除"Bearer "前缀
            System.out.println("token= "+token);
            if ( token.isEmpty()) {

                throw new GlobalException(ErrorEnum.NO_TOKEN_FOUND);

            }

            if(!jwtTokenUtil.validateToken(token)){

                throw new GlobalException(ErrorEnum.ILLEGAL_TOKEN);

        }
        //token是否过期
        if(jwtTokenUtil.isTokenExpired(token)){

            throw new GlobalException(ErrorEnum.EXPIRED_TOKEN);
//
            }
        //用户存在
            String username=jwtTokenUtil.getUsernameFromToken(token);
            User foundUser=userMapper.findByUsername(username);
        if(foundUser==null){
            throw new GlobalException(ErrorEnum.NO_USER_FOUND);
//            response.sendError(HttpStatus.UNAUTHORIZED.value(), "用户不存在");

        }
            //获取到当前用户，最后塞进request中

//        List<UserRole> userRoles = roleMapper.getUserRoleByUserId(Math.toIntExact(foundUser.getId()));
//        foundUser.setRoles(userRoles.stream().map(UserRole::getRoleId).distinct().collect(Collectors.toList()));
        request.setAttribute("current_user", foundUser);

//        System.out.println("current_user.gender"+foundUser.getGender());


            //接口限流
            if(handler instanceof HandlerMethod){
                HandlerMethod hm = (HandlerMethod) handler;
                AccessLimit accessLimit=hm.getMethodAnnotation(AccessLimit.class);
                if(accessLimit==null) return true;
                int seconds=accessLimit.seconds();
                int maxCount=accessLimit.seconds();
                String key=request.getRequestURI();
                ValueOperations valueOperations=redisTemplate.opsForValue();

                Integer count=(Integer) valueOperations.get(key);
                if(count==null) valueOperations.set(key,1,seconds, TimeUnit.SECONDS);
                else  if(count<maxCount) valueOperations.increment(key);
                else {
                    System.out.println("过于频繁");
                    throw new GlobalException(ErrorEnum.ACCESS_LIMIT_REACHED);
//                    response.sendError(ErrorEnum.ACCESS_LIMIT_REACHED.getCode(),ErrorEnum.ACCESS_LIMIT_REACHED.getMessage());

                }



            }


            return true;







    }

//    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        // 在请求处理之后，视图渲染之前执行的操作
        System.out.println("=====postHandle=====");
    }

//    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                Exception ex) throws Exception {
        // 在请求完成之后执行的操作，即视图渲染完成后
        System.out.println("=====afterCompletion=====");
    }

}
